﻿using Awsc.DataAcquisitionSys.Core.Model.Config;
using Awsc.DataAcquisitionSys.Core.Models.ServiceModels;
using Awsc.DataAcquisitionSys.Core.Service.DataAcquisition.DataCollectors;

namespace Awsc.DataAcquisitionSys.Core.Services.DataAcquisition.DataCollectors.Sensors
{
    public class Sensor
    {
        private object _value;
        public string Name { get; set; }
        public int CollectorChannelId { get; set; }
        public SensorConfig SensorConfig { get; set; }
        public DataCollector DataCollector { get; set; }
        public DevStatus Status { get; set; }
        public bool IsDICoil
        {
            get
            {
                if (SensorConfig == null || !SensorConfig.IsCoil)
                {
                    return false;
                }
                var config = SensorConfig as CoilConfig;
                if (config == null)
                {
                    return false;
                }
                return config.CoilType == CoilType.DI;
            }
        }

        public bool IsDOCoil
        {
            get
            {
                if (SensorConfig == null || !SensorConfig.IsCoil)
                {
                    return false;
                }
                var config = SensorConfig as CoilConfig;
                if (config == null)
                {
                    return false;
                }
                return config.CoilType == CoilType.DO;
            }
        }

        public bool NeedCreateAICoil
        {
            get
            {
                if (SensorConfig == null || !IsAIRegister)
                {
                    return false;
                }
                var config = SensorConfig as RegisterConfig;
                return config.CreatAICoil;
            }
        }

        public string Unit
        {
            get
            {
                if (SensorConfig == null || SensorConfig.IsCoil)
                {
                    return "";
                }
                var config = SensorConfig as RegisterConfig;
                return config.RangeUnit;
            }
        }



        public bool IsAiCoil
        {
            get
            {
                return SensorConfig != null && SensorConfig.IsCoil && SensorConfig.CollectorChannelId == 999;
            }
        }

        public bool IsAIRegister
        {
            get
            {
                if (SensorConfig == null)
                {
                    return false;
                }
                if (SensorConfig.IsCoil)
                {
                    return false;
                }
                var config = SensorConfig as RegisterConfig;
                if (config == null)
                {
                    return false;
                }
                return config.RegisterType == RegisterType.AI;
            }
        }
        public bool IsAORegister
        {
            get
            {
                if (SensorConfig == null)
                {
                    return false;
                }
                if (SensorConfig.IsCoil)
                {
                    return false;
                }
                var config = SensorConfig as RegisterConfig;
                if (config == null)
                {
                    return false;
                }
                return config.RegisterType == RegisterType.AO;
            }
        }


        public event EventHandler ValueChanged;

        public object OutputValue
        {
            get
            {
                if (!IsValid)
                {
                    Status = DevStatus.S_UNKNOWN;
                    return null;
                }
                return _value;
            }
            set
            {
                _value = value;
                Timestamp = DateTime.UtcNow.Ticks;
                Status = DevStatus.S_OK;
            }
        }

        private object _currentValue;
        public  object CurrentValue
        {
            get
            {
                CalculateValue();
                if (!IsValid)
                {
                    Status = DevStatus.S_UNKNOWN;
                    return null;
                }
                return _currentValue;
            }
            set
            {
                _currentValue = value;
                Timestamp = DateTime.UtcNow.Ticks;
                Status = DevStatus.S_OK;
                ValueChanged?.Invoke(this, EventArgs.Empty);
            }
        }

        protected virtual void CalculateValue()
        {
            _currentValue = _value;
        }
        public long Timestamp { get; set; }

        public bool IsValid
        {
            get
            {
                if (_value == null)
                {
                    return false;
                }
                TimeSpan expirationTime = TimeSpan.FromSeconds(10);
                return DateTime.UtcNow.Ticks - Timestamp <= expirationTime.Ticks;
            }
        }

        public override string ToString()
        {
            return $"{Name}:{CurrentValue}- {Status.ToString()}";
        }
    }


}
